package com.cskaoyan.javase.array._4operation._3crud;

import java.util.Arrays;
import java.util.Scanner;

/**
 * 数组元素的增删改查
 * 数组是一个容器，可以用存放元素，存放数据。
 * 在实际开发中，工程中也会需要存放大量数据，这一般是通过数据库来实现的。
 * 实际开发的基本需求就是基于数据库的，对数据进行增删改查，即"crud"，也有很多中低级Java程序员自嘲自己为"crud工程师"。
 *
 * 当然"crud"指的是：
 * c，create：新增数据/增加。
 * r，retrieve：检索数据/查询。
 * u，update：更新数据/修改。
 * d，delete ：删除数据/删除。
 * 我们现在还没有学习过数据库，但是不重要。现在我们使用数组这个容器，来模拟数据库，实现日常开发中最常见的"crud"操作。
 *
 * 需求:
 *      给出一个人名的String数组
 *      要求,其中的人名都是唯一的,不可重复的
 *      然后完成增删改查四个操作(写四个方法)
 *
 * @since 16:17
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        String[] names = new String[10];
        names[0] = "张三";
        names[1] = "李四";
        names[2] = "王五";
        names[3] = "麻子";
        names[4] = "狗蛋";
        System.out.println("---开始进行插入操作---");
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入一个被插入的人名:");
        String targetName = sc.nextLine();
        switch (createName(names, targetName)) {
            case 0:
                System.out.println("插入成功!");
                System.out.println(Arrays.toString(names));
                break;
            case 1:
                System.out.println("数组满了,插入失败!");
                System.out.println(Arrays.toString(names));
                break;
            case 2:
                System.out.println("人名重复,插入失败!");
                System.out.println(Arrays.toString(names));
                break;
        }
    }

    // 增
    /*
        增加的需求:
        数组是不可能真的新增一个元素的(数组的长度不可变)
        所以这里的新增指的是
        用一个人名字符串对象,取代原先null元素的位置
        所以,分析一下,这个新增的操作,结果可能是:
            1.数组满了,没有null的位置,新增失败.
            2.人名已经存在了,新增重复的人名,新增失败
            3.以上两种情况都没有出现,新增成功
        这时方法的执行结果可能有三种
        于是设计方法会根据不同的执行结果返回不同的状态码,指示方法的执行结果:
            1.如果返回0,表示新增成功
            2.如果返回1,表示数组满了
            3.如果返回2,表示人名重复了
     */

    /**
     * 该方法将一个目标人名新增到目标数组中,方法的执行会有三种结果:
     *      1.如果返回0,表示新增成功
     *      2.如果返回1,表示数组满了
     *      3.如果返回2,表示人名重复了
     *
     * @param targetArr 新增人名的目标数组
     * @param targetName 新增的目标人名
     * @return int
     * @author wuguidong@cskaoyan.onaliyun.com
     * @since 2022/09/29 16:27
     */
    public static int createName(String[] targetArr, String targetName) {
        // 1.先判断一下传入的目标人名是否已经存在了,如果存在,新增失败
        // 具体来说,就是遍历整个数组,然后逐一比对,看一看是否重复
        for (String name : targetArr) {
            /*if (name == null) {
                continue;
            }*/
            if (targetName.equals(name)) {
                // 人名重复了
                return 2;
            }
        }
        // 2.如果人名没有重复,开始遍历数组找到一个null元素的位置,进行新增操作
        // 如果插入成功,说明数组没有满,如果遍历完整个数组都没有插入成功,说明数组满了
        // 具体来说,就是开始进行插入操作,遍历数组,找到null的位置,就赋值,插入成功
        for (int i = 0; i < targetArr.length; i++) {
            if (targetArr[i] == null) {
                // 还有空位置,赋值,表示插入成功
                targetArr[i] = targetName;
                return 0;
            }
        }
        // 代码运行到这里,说明没有找到null的位置,插入失败
        return 1;
    }
    /**
     * 在给定数组中，删除目标人名，规定:
     *    删除成功,返回true
     *    删除失败,返回false
     *
     * @param target 目标数组
     * @param nameTarget 被删除的目标人名
     * @return boolean
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static boolean deleteName(String[] target, String nameTarget) {
        // 遍历查找目标元素,找到了就赋值为null
        for (int i = 0; i < target.length; i++) {
            // 判断目标人名和数组中人名是否重复,重复就说明存在,删除掉(赋值为null)
            if (nameTarget.equals(target[i])) {
                // 找到了
                target[i] = null;
                return true;
            }
        }
        // 代码运行到这里,说明没找到目标元素,删除失败
        return false;
    }
    // 改
    /**
     * 找到目标人名，修改成功,返回true
     * 没找到目标人名，修改失败,返回false
     *
     * @param names 被修改人名的目标数组
     * @param target 被修改的目标人名
     * @param newValue 修改后的取值
     * @return boolean
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static boolean updateName(String[] names, String target, String newValue) {
        for (int i = 0; i < names.length; i++) {
            if (target.equals(names[i])) {
                // 找到了,修改为新的取值,更新成功
                names[i] = newValue;
                return true;
            }
        }
        // 修改失败,没找到元素
        return false;
    }

    // 查
    /**
     * 查找目标人名,找到了就返回目标人名在数组中的下标
     * 没找到就返回-1
     *
     * @param names
     * @param target
     * @return int
     * @author wuguidong@cskaoyan.onaliyun.com
     */
    public static int retrieveName(String[] names, String target) {
        /*
            首先需要定义一个目标下标作为返回的结果下标
            给出一个初始值-1
            因为数组下标肯定不可能是-1,表示没找到目标人名
         */
        int targetIndex = -1;
        for (int i = 0; i < names.length; i++) {
            if (target.equals(names[i])) {
                // 找到了
                targetIndex = i;
            }
        }
        // 没找到,直接就返回-1
        return targetIndex;
    }
}
